package com.g2room.lab.graphQL;

import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.StaticDataFetcher;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;

import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring;

public class GraphQLSample {
    public static void main(String[] args) {
        // 1\. 定义Schema, 一般会定义在一个schema文件中
        // schema就是协议，规范，或者可以当他是接口文档。就跟我们平时生成的swagger文档一样，定义接口是什么，参数是什么，返回值有哪些，类型是什么，哪些值不能为空等等。
        /**
         GraphQL规定，每一个schema有一个根(root)query和根(root)mutation，还有一种subscription类型，我们暂时用不上。
             query即定义查询接口，当然这只是一种语义规范，在接口里写更改操作也是可以的，但是不推荐。
             mutation即定义更改接口，同上也是一种语义规范。
             在目前的GraphQL实现中，只能定义一个schema文件，一个文件中只能定义一个query和mutation，如果要定义多个会报错。
         数据类型：
             GraphQL定义了ID【相当于String类型，GraphQL用来自己实现缓存】，Int（整型）, Float（浮点型）【Java中实现为Double类型】, String（字符串）, Boolean（布尔型）和ID（唯一标识符类型）五个基本类型，在GraphQL中他们统称叫标量类型(Scalar Type)，java实现中实现了更多的类型都定义在graphql.Scalars类中，比如BigInteger、BigDecimal等。GraphQL允许我们自定义标量类型，比如Data类型，只需实现相关的序列化，反序列化和验证的功能即可。已有实现参看这里：https://github.com/graphql-java/graphql-java-extended-scalars
             !用来表示这个参数是非空的。[]表示查询这个字段返回的是数组(List)，[]里面是数组的类型。
         对象类型：
             用type来定义对象类型，就跟Java用class来定义一个类一样。
             用input来定义接口输入类型，即接口中的输入对象。
         */
        String schema = "type Query{hello: String}";
        // 2\. 解析Schema
        SchemaParser schemaParser = new SchemaParser();
        TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);
        // 为Schema 中hello方法绑定获取数据的方法
        RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring()
                // 这里绑定的是最简单的静态数据数据获取器, 正常使用时,获取数据的方法返回一个DataFetcher实现即可
                .type("Query", builder -> builder.dataFetcher("hello", new StaticDataFetcher("world")))
                .build();
        // 将TypeDefinitionRegistry与RuntimeWiring结合起来生成GraphQLSchema
        SchemaGenerator schemaGenerator = new SchemaGenerator();
        GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
        // 实例化GraphQL, GraphQL为执行GraphQL语言的入口
        GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();
        // 执行查询
        ExecutionResult executionResult = graphQL.execute("{hello}");
        // 打印执行结果
        System.out.println(executionResult.getData().toString());
    }
}
